﻿using Kaskelot.SP.Core;
using Microsoft.SharePoint;
using Precio.Logging.Facade.Behaviors;
using Stockholm.SOA.Kaskelot.WCF.DataContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Text;

namespace Kaskelot.SP.Services
{
    public class BaseService<T> : IDisposable
    {
        protected ChannelFactory<T> factory;
        internal T channel;

        public BaseService()
        {
            //EndpointAddress address = new EndpointAddress(ConfigManager.General.KaskelotServiceEndpoint);

            //this.factory = new ChannelFactory<T>(GetBinding(), address);
            //this.factory.Endpoint.Behaviors.Add(new CallContextBehavior());
            //this.factory.Endpoint.Behaviors.Add(new MessageIOLoggingBehavior());
            //foreach (var op in this.factory.Endpoint.Contract.Operations)
            //{
            //    DataContractSerializerOperationBehavior beh = op.Behaviors.Find<DataContractSerializerOperationBehavior>();
            //    if (beh != null)
            //        beh.MaxItemsInObjectGraph = int.MaxValue;
            //}
            this.factory = new ChannelFactory<T>("Kaskelot_Service_Endpoint");
            this.factory.Open();
            this.channel = this.factory.CreateChannel();
        }

        private static System.ServiceModel.Channels.Binding GetBinding()
        {
            WSHttpBinding binding = new WSHttpBinding(SecurityMode.None);
            binding.MaxReceivedMessageSize = int.MaxValue;
            binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
            return binding;
        }

        public void Dispose()
        {
            if (factory.State == CommunicationState.Opened)
                factory.Close();
            else if (factory.State == CommunicationState.Faulted)
                factory.Abort();

            if (((IChannel)this.channel).State == CommunicationState.Opened)
                ((IChannel)this.channel).Close();
            else if (((IChannel)this.channel).State == CommunicationState.Faulted)
                ((IChannel)this.channel).Abort();
        }

		protected void CheckWriteAllowed()
		{
            CheckWriteAllowed(ApplicationContext.Current.Val);
		}

		protected void CheckWriteAllowed(Val v)
		{
			if(!v.Aktivt)
				throw new ApplicationException("Valet är låst och kan inte redigeras.");
            if (SPContext.Current != null && !AuthService.IsInRole(AuthService.Permissions.Write))
                throw new ApplicationException("Inloggad användare saknar behörighet att redigera information.");
		}
    }
}
